package com.linkoog.devtools.json.toolwindow.ui;

import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
import com.intellij.util.ui.ColumnInfo;
import com.linkoog.devtools.json.toolwindow.ui.jsontree.JsonTreeNode;
import com.linkoog.devtools.json.toolwindow.ui.jsontree.TableKeyRenderer;
import com.linkoog.devtools.json.toolwindow.ui.jsontree.TreeKeyCellRenderer;
import com.linkoog.devtools.json.toolwindow.ui.jsontree.TableValueRenderer;
import org.apache.commons.lang3.StringUtils;

import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;


import static java.lang.Math.max;

public class JsonTreeTableView extends TreeTable {

    TreeTableTree tree;
    TreeNode rootNode;



    public JsonTreeTableView(TreeNode rootNode){
        super(new ListTreeTableModelOnColumns(rootNode, columns));
        this.rootNode = rootNode;
        init();
    }

    private void init(){
        tree = getTree();
        tree.setShowsRootHandles(true);
        tree.setRootVisible(false);
        setTreeCellRenderer(new TreeKeyCellRenderer());

        int keyColumnWidth = getFontMetrics(getFont()).stringWidth(StringUtils.repeat("*", getMaxKeyColumnWidth(rootNode)));
        final TableColumn column = getColumnModel().getColumn(0);
        column.setMaxWidth(keyColumnWidth);
        column.setPreferredWidth(keyColumnWidth);
        setAutoResizeMode(AUTO_RESIZE_LAST_COLUMN);
    }

    private int getMaxKeyColumnWidth(TreeNode rootNode) {
        var length = 0;
        if (!rootNode.isLeaf()) {
            var maxChildLen = 0;
            for (int i = 0; i < rootNode.getChildCount(); i++) {
                maxChildLen = max(getMaxKeyColumnWidth(rootNode.getChildAt(i)), maxChildLen);
            }
            length += maxChildLen;
        }

        if (rootNode instanceof JsonTreeNode){
            JsonTreeNode node = (JsonTreeNode)rootNode;
            length += node.getName().length();
        }

        return length;
    }

    /*public TableCellRenderer getCellRenderer(int row, int column){
        TreePath treePath = tree.getPathForRow(row);
        if (treePath == null){
            return super.getCellRenderer(row, column);
        }

        JsonTreeNode node = (JsonTreeNode)treePath.getLastPathComponent();
        TableCellRenderer renderer = columns[column].getRenderer(node);
        if (renderer == null){
            super.getCellRenderer(row, column);
        }

        return renderer;
    }*/

    public TableCellEditor getCellEditor(int row, int column) {
        TreePath treePath = tree.getPathForRow(row);
        if (treePath == null){
            return super.getCellEditor(row, column);
        }

        JsonTreeNode node = (JsonTreeNode)treePath.getLastPathComponent();
        TableCellEditor editor = columns[column].getEditor(node);
        if (editor == null){
            return super.getCellEditor(row, column);
        }
        return editor;
    }

    private static final ColumnInfo<JsonTreeNode, String> KEY = new  ColumnInfo<>("Key") {
        public String valueOf(JsonTreeNode treeNode)  {
            return treeNode.getName();
        }

        public Class<TreeTableModel> getColumnClass() {
            return TreeTableModel.class;
        }

         public boolean isCellEditable(JsonTreeNode treeNode) {
            return false;
        }

        public TableCellRenderer getRenderer(JsonTreeNode treeNode) {
            return new TableKeyRenderer();
        }

        @Override
        public int getAdditionalWidth() {
            return 4;
        }
    };

    private static final ColumnInfo<JsonTreeNode, String> VALUE = new ColumnInfo<>("Value") {

        public String valueOf(JsonTreeNode treeNode) {
            return treeNode.getJson();
        }

        public boolean isCellEditable(JsonTreeNode treeNode) {
            return false;
        }

        public TableCellRenderer getRenderer(JsonTreeNode treeNode) {
            return new TableValueRenderer();
        }
    };

    private static final ColumnInfo[] columns = new ColumnInfo[]{KEY, VALUE};


}
